package cn.tannn.captcha.sdk.generator;

import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.math.Calculator;
import cn.hutool.core.util.RandomUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 数学验证码生成器
 *
 * @author <a href="https://t.tannn.cn/">tan</a>
 * @version V1.0
 * @date 2025/1/6 12:13
 */
public class EnhancedMathGenerator implements CodeGenerator {
    private static final long serialVersionUID = -5514819971774091076L;
    private static final Logger LOG = LoggerFactory.getLogger(EnhancedMathGenerator.class);

    private static final String operators = "+-*";

    /** 参与计算数字最大长度 */
    private final int numberLength;

    /** 是否只生成绝对值结果 */
    private final boolean absoluteValue;

    /**
     * 构造 - 默认绝对值模式
     */
    public EnhancedMathGenerator() {
        this(2, true);
    }

    /**
     * 构造
     *
     * @param numberLength 参与计算最大数字位数
     * @param absoluteValue 是否只生成绝对值结果
     */
    public EnhancedMathGenerator(int numberLength, boolean absoluteValue) {
        this.numberLength = numberLength;
        this.absoluteValue = absoluteValue;
    }

    @Override
    public String generate() {
        final int limit = getLimit();
        int num1 = RandomUtil.randomInt(1, limit);
        int num2 = RandomUtil.randomInt(1, limit);

        char operator = RandomUtil.randomChar(operators);

        // 如果需要绝对值结果，确保减法不产生负数
        if (absoluteValue && operator == '-' && num1 < num2) {
            int temp = num1;
            num1 = num2;
            num2 = temp;
            LOG.debug("Math captcha abs dispose: {} - {}", num1, num2);
        }

        // 返回 "xx + xx = ?" 格式
        return num1 + " " + operator + " " + num2 + " = ?";
    }

    @Override
    public boolean verify(String code, String userInputCode) {
        int result;
        try {
            result = Integer.parseInt(userInputCode.trim());
        } catch (NumberFormatException e) {
            LOG.warn("User input is not a valid number: {}", userInputCode);
            return false;
        }

        // 从code中提取表达式并计算
        String expression = code.replace(" = ?", "");
        try {
            final int calculateResult = (int) Calculator.conversion(expression);
            return result == calculateResult;
        } catch (Exception e) {
            LOG.error("Error calculating expression: {}", expression, e);
            return false;
        }
    }

    /**
     * 获取验证码长度
     *
     * @return 验证码长度
     */
    public int getLength() {
        return this.numberLength * 2 + 6; // "xx + xx = ?" 的长度
    }

    /**
     * 根据长度获取参与计算数字最大值
     *
     * @return 最大值
     */
    private int getLimit() {
        return (int) Math.pow(10, this.numberLength);
    }
}
